///////////////////////////////////////////////////////////////////////////////
///// Assignment 3: CPU Scheduler
///// By: Brady Robichaud (robicb82) & Patrick Filtz (filtzp43)
///// Date: 4/19/2013
///// Main Files: Main.java
///// Files: FCFS.java, FCFSQ.java, MFQ.java, Node.java, Process.java, 
/////  	Queue.java, RR.java, SJFNP.java, SJFP.java, & Windows.java
/////
///// Description: An ability to design, implement and evaluate a 
/////	computer-based system, process, component, or program to 
/////	meet desired needs.
///////////////////////////////////////////////////////////////////////////////
package round2;

import java.util.ArrayList;
import java.util.Random;

public class Main {
	static int numProcs = 0;
	static ArrayList<Process> procs = new ArrayList<Process>();
	static Random rand = new Random();
	
	//Array of processes to be added to each of the
	public static String addProc(){
		Process p = new Process(++numProcs, rand.nextInt(numProcs*2), getRandomBursts(10));
		procs.add(p);
		return p.toString();
	}
	
	public static String run(){
		String output = "";
		Process[] ps = new Process[procs.size()];
		
		//First come first serve
		for(int i = 0; i < ps.length; i++){
			ps[i] = procs.get(i).copyMe();
		}
		FCFS q1 = new FCFS(ps);
		output += q1.run() + "\n\n";
		
		// Shortest job first non-preemptive
		for(int i = 0; i < ps.length; i++){
			ps[i] = procs.get(i).copyMe();
		}
		SJFNP q2 = new SJFNP(ps);
		output += q2.run() + "\n";
		
		// Shortest job first preemptive
		for(int i = 0; i < ps.length; i++){
			ps[i] = procs.get(i).copyMe();
		}
		SJFP q3 = new SJFP(ps);
		output += q3.run() + "\n";
		
		// Round Robin
		for(int i = 0; i < ps.length; i++){
			ps[i] = procs.get(i).copyMe();
		}
		RR q4 = new RR(ps, rand.nextInt(21));
		output += q4.run() + "\n";
		
		// Multilevel Feedback Queue
		for(int i = 0; i < ps.length; i++){
			ps[i] = procs.get(i).copyMe();
		}
		MFQ q5 = new MFQ(ps, 8);
		output += q5.run() + "\n";

		return output + "\n";
	}
	
	
	public static void main(String[] args){
		//Used for testing manual processes, prints to terminal only 
		/*
		int[] p1Times = {53};
		Process p1 = new Process(1, 0, p1Times); //Process number, Arrival time
		
		int[] p2Times = {17};
		Process p2 = new Process(2, 2, p2Times);
		
		int[] p3Times = {68};
		Process p3 = new Process(3, 4, p3Times);
		
		int[] p4Times = {24};
		Process p4 = new Process(4, 5, p4Times);
		
		Process[] ps1 = {p1,p2, p3, p4};
		
		MFQ q2 = new MFQ(ps1, rand.nextInt(21));
		System.out.println(q2.run());	
		 */
	}
	
	//Clears the processes 
	public static void clearAll(){
		procs.clear();
		numProcs = 0;
	}
	
	//Creates the randomized bursts for CPU and IO
	private static int[] getRandomBursts(int range){
		Random r = new Random();
		int size = r.nextInt(10) + 1;
		int[] out = new int[size];
		
		for(int i = 0; i < out.length; i++){
			out[i] = r.nextInt(range) + 1;
		}		
		return out;
	}
	
	//Deep copy of processes, ran for each type of scheduler
	private static int[] deepCopy(int[] copyMe){
		int[] dc = new int[copyMe.length];
		for(int i = 0; i < copyMe.length; i++){
			dc[i] = copyMe[i];
		}
		return dc;
	}
}
